// Copyright 2009 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.package flate// Sort sorts data.// It makes one call to data.Len to determine n, and O(n*log(n)) calls to// data.Less and data.Swap. The sort is not guaranteed to be stable.func ( []literalNode) { := len()quickSortByFreq(, 0, , maxDepth())}func ( []literalNode, , , int) {for - > 12 { // Use ShellSort for slices <= 12 elementsif == 0 {heapSort(, , )return } -- , := doPivotByFreq(, , )// Avoiding recursion on the larger subproblem guarantees // a stack depth of at most lg(b-a).if - < - { (, , , ) = // i.e., quickSortByFreq(data, mhi, b) } else { (, , , ) = // i.e., quickSortByFreq(data, a, mlo) } }if - > 1 {// Do ShellSort pass with gap 6 // It could be written in this simplified form cause b-a <= 12for := + 6; < ; ++ {if [].freq == [-6].freq && [].literal < [-6].literal || [].freq < [-6].freq { [], [-6] = [-6], [] } }insertionSortByFreq(, , ) }}func ( []literalNode, , int) (, int) { := int(uint(+) >> 1) // Written like this to avoid integer overflow.if - > 40 {// Tukey's ``Ninther,'' median of three medians of three. := ( - ) / 8medianOfThreeSortByFreq(, , +, +2*)medianOfThreeSortByFreq(, , -, +)medianOfThreeSortByFreq(, -1, -1-, -1-2*) }medianOfThreeSortByFreq(, , , -1)// Invariants are: // data[lo] = pivot (set up by ChoosePivot) // data[lo < i < a] < pivot // data[a <= i < b] <= pivot // data[b <= i < c] unexamined // data[c <= i < hi-1] > pivot // data[hi-1] >= pivot := , := +1, -1for ; < && ([].freq == [].freq && [].literal < [].literal || [].freq < [].freq); ++ { } := for {for ; < && ([].freq == [].freq && [].literal > [].literal || [].freq > [].freq); ++ { // data[b] <= pivot }for ; < && ([].freq == [-1].freq && [].literal < [-1].literal || [].freq < [-1].freq); -- { // data[c-1] > pivot }if >= {break }// data[b] > pivot; data[c-1] <= pivot [], [-1] = [-1], [] ++ -- }// If hi-c<3 then there are duplicates (by property of median of nine). // Let's be a bit more conservative, and set border to 5. := - < 5if ! && - < (-)/4 {// Lets test some points for equality to pivot := 0if [].freq == [-1].freq && [].literal > [-1].literal || [].freq > [-1].freq { // data[hi-1] = pivot [], [-1] = [-1], [] ++ ++ }if [-1].freq == [].freq && [-1].literal > [].literal || [-1].freq > [].freq { // data[b-1] = pivot -- ++ }// m-lo = (hi-lo)/2 > 6 // b-lo > (hi-lo)*3/4-1 > 8 // ==> m < b ==> data[m] <= pivotif [].freq == [].freq && [].literal > [].literal || [].freq > [].freq { // data[m] = pivot [], [-1] = [-1], [] -- ++ }// if at least 2 points are equal to pivot, assume skewed distribution = > 1 }if {// Protect against a lot of duplicates // Add invariant: // data[a <= i < b] unexamined // data[b <= i < c] = pivotfor {for ; < && ([-1].freq == [].freq && [-1].literal > [].literal || [-1].freq > [].freq); -- { // data[b] == pivot }for ; < && ([].freq == [].freq && [].literal < [].literal || [].freq < [].freq); ++ { // data[a] < pivot }if >= {break }// data[a] == pivot; data[b-1] < pivot [], [-1] = [-1], [] ++ -- } }// Swap pivot into middle [], [-1] = [-1], []return - 1, }// Insertion sortfunc ( []literalNode, , int) {for := + 1; < ; ++ {for := ; > && ([].freq == [-1].freq && [].literal < [-1].literal || [].freq < [-1].freq); -- { [], [-1] = [-1], [] } }}// quickSortByFreq, loosely following Bentley and McIlroy,// ``Engineering a Sort Function,'' SP&E November 1993.// medianOfThreeSortByFreq moves the median of the three values data[m0], data[m1], data[m2] into data[m1].func ( []literalNode, , , int) {// sort 3 elementsif [].freq == [].freq && [].literal < [].literal || [].freq < [].freq { [], [] = [], [] }// data[m0] <= data[m1]if [].freq == [].freq && [].literal < [].literal || [].freq < [].freq { [], [] = [], []// data[m0] <= data[m2] && data[m1] < data[m2]if [].freq == [].freq && [].literal < [].literal || [].freq < [].freq { [], [] = [], [] } }// now data[m0] <= data[m1] <= data[m2]}
The pages are generated with Goldsv0.6.7. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds.